home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
2410
/
2410.xpi
/
components
/
foxmarks-service.js
next >
Wrap
Text File
|
2010-01-28
|
42KB
|
1,278 lines
/*
Copyright 2005-2008 Foxmarks Inc.
foxmarks-service.js: component that implements the "service" interface to
the core synchronization code.
*/
var Cc = Components.classes;
var Ci = Components.interfaces;
var Xmarks;
if(Xmarks === undefined){
Xmarks = {};
}
function LoadJavascript(filename, id) {
if (id == "undefined") {
Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader).
loadSubScript(filename, null);
}
}
function GetTopWin(wintype) {
var topwin = Cc['@mozilla.org/appshell/window-mediator;1'].
getService(Ci.nsIWindowMediator).
getMostRecentWindow(wintype);
return topwin;
}
function FoxmarksSetCookie() {
var url = "http://www.xmarks.com";
var d = new Date();
d.setTime(d.getTime() + (20 * 365 * 24 * 60 * 60 * 1000));
var cm = Components.classes["@mozilla.org/cookiemanager;1"].
getService(Components.interfaces.nsICookieManager2);
cm.add(".xmarks.com", "/", "mid", Xmarks.gSettings.machineId, false, false, false,
d.getTime() / 1000);
}
function FoxmarksLaunchUpgradePage() {
FoxmarksSetCookie();
upgradeCallback.timer = Cc["@mozilla.org/timer;1"].
createInstance(Ci.nsITimer);
upgradeCallback.timer.initWithCallback(upgradeCallback, 5000,
Ci.nsITimer.TYPE_ONE_SHOT);
}
function FoxmarksBuildPostData(num_bookmarks){
return {
username: Xmarks.gSettings.username,
version: Xmarks.FoxmarksVersion(),
types: {
bookmarks: {
is_enabled: Xmarks.gSettings.isSyncEnabled("bookmarks"),
count: num_bookmarks
},
passwords: {
is_enabled: Xmarks.gSettings.isSyncEnabled("passwords")
}
}
};
}
var upgradeCallback = {
notify: function(timer) {
FoxmarksSyncService.server.countItems("bookmarks",
"bookmark", function(status, num_bookmarks){
var currver = Xmarks.FoxmarksVersion();
var wm = Cc['@mozilla.org/appshell/window-mediator;1'].
getService(Ci.nsIWindowMediator);
var topWindow = wm.getMostRecentWindow('navigator:browser');
if(topWindow &&
topWindow.document){
var appcontent =
topWindow.document.getElementById("appcontent");
var listener = function(e){
var doc = e.originalTarget;
var button =
doc.getElementById(
"set_up_password_sync_button"
);
if(button){
button.setAttribute("onclick", null);
button.addEventListener(
"click",
function(){
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
os.notifyObservers(null,
"foxmarks-showsettingpane",
"foxmarks-syncpane"
);
},
true
);
appcontent.removeEventListener(
"DOMContentLoaded",
listener,
false
);
}
};
if(appcontent){
appcontent.addEventListener(
"DOMContentLoaded",
listener,
false
);
}
}
// We used to set the protocol as Xmarks.gSettings.httpProtocol,
// but that causes warnings when that page references non-HTTPS
// ads, so we peg the protocol as http.
Xmarks.OpenInNewTab("http://" + Xmarks.gSettings.webHost +
"/firefox/upgrade/" + currver, true,
FoxmarksBuildPostData(num_bookmarks));
Xmarks.gSettings.currVersion = currver;
});
}
}
function FoxmarksCheckForServerChanges() {
if(Xmarks.gSettings.useOwnServer){
var os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
os.notifyObservers(null, "foxmarks-realstart", "");
} else {
var url = Xmarks.gSettings.httpProtocol + Xmarks.gSettings.apiHost +
"/internal/serverprefs";
var request = new Request(
"POST",
url,
{
mid: Xmarks.gSettings.machineId,
version: Xmarks.gSettings.serverVersion,
abgroup: Xmarks.gSettings.abgroup,
cid: "xmfx"
},
{
isAuthRequest: false,
headers: null,
ignoreBody: false,
ignoreAuthTokens: true
}
);
request.Start(function(response){
if(response && response.status === 0){
if(response.version > Xmarks.gSettings.serverVersion){
if(response.prefs){
var prefs = response.prefs;
for(var pref in prefs){
if(prefs.hasOwnProperty(pref)){
Xmarks.gSettings[pref] = prefs[pref];
}
}
}
Xmarks.gSettings.serverVersion = response.version;
}
}
var os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
os.notifyObservers(null, "foxmarks-realstart", "");
});
}
}
function FoxmarksLaunchSetupWizard() {
FoxmarksSetCookie();
FoxmarksWizardCallback.timer = Cc["@mozilla.org/timer;1"].
createInstance(Ci.nsITimer);
FoxmarksWizardCallback.timer.initWithCallback(FoxmarksWizardCallback, 5000,
Ci.nsITimer.TYPE_ONE_SHOT);
}
var FoxmarksWizardCallback = {
notify: function(timer) {
var url = "http://" + Xmarks.gSettings.staticHost + Xmarks.gSettings.wizardPrefs;
var request = new Request(
"GET",
url,
null,
{
isAuthRequest: false,
headers: null,
ignoreBody: false,
ignoreAuthTokens: true
}
);
request.Start(function(response){
var os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
var JSON = Cc["@mozilla.org/dom/json;1"].
createInstance(Ci.nsIJSON);
os.notifyObservers(null, "foxmarks-newpopup", JSON.encode(response));
});
}
}
function HandleShutdown(cancel) {
var retval = { helpurl: null };
var sb = Xmarks.Bundle().GetStringFromName;
var dontask = {value: false};
var rv = 0;
if (!Xmarks.gSettings.haveSynced || GetState() != "dirty") {
return;
}
var topwin = GetTopWin();
if (!topwin) {
Xmarks.LogWrite("HandleShutdown: Couldn't find a topwin!");
return;
}
if (Xmarks.gSettings.syncOnShutdown && Xmarks.gSettings.syncOnShutdownAsk) {
rv = Cc["@mozilla.org/embedcomp/prompt-service;1"].
getService(Ci.nsIPromptService).
confirmEx(topwin, sb("appname.long"), sb("msg.unsynced"),
Ci.nsIPromptService.STD_YES_NO_BUTTONS, null, null, null,
sb("msg.dontask"), dontask);
// Reverse sense: confirmEx returns 0 - yes, 1 - no
rv = !rv;
// If user says "don't ask me again", set syncOnShutdown to whatever
// they have chosen in this instance.
if (dontask.value) {
Xmarks.gSettings.syncOnShutdown = rv;
}
Xmarks.gSettings.syncOnShutdownAsk = !dontask.value;
} else { // don't ask
rv = Xmarks.gSettings.syncOnShutdown;
}
if (rv) {
var win = topwin.openDialog(
"chrome://foxmarks/content/foxmarks-progress.xul", "_blank",
"chrome,dialog,modal,centerscreen", "synch", retval, null);
if (retval.helpurl) { // we hit an error and user pressed help button
if (cancel instanceof Ci.nsISupportsPRBoolean) {
cancel.value = true;
topwin.openDialog("chrome://browser/content/browser.xul",
"_blank", "chrome,all,dialog=no", retval.helpurl);
}
}
}
}
function LoadFiles() {
LoadJavascript("chrome://foxmarks/content/foxmarks-log.js",
typeof(Xmarks.LogWrite));
LoadJavascript("chrome://foxmarks/content/foxmarks-settings.js",
typeof(Xmarks.gSettings));
LoadJavascript("chrome://foxmarks/content/foxmarks-update.js",
typeof(ForceUpdate));
LoadJavascript("chrome://foxmarks/content/foxmarks-clobber.js",
typeof(onClobberCancel));
LoadJavascript("chrome://foxmarks/content/foxmarks-bookmark.js",
typeof(loadDatasourceSet));
if ("@mozilla.org/browser/nav-bookmarks-service;1" in Cc)
LoadJavascript("chrome://foxmarks/content/foxmarks-places.js",
typeof(BookmarkDatasource));
else
LoadJavascript("chrome://foxmarks/content/foxmarks-rdf.js",
typeof(BookmarkDatasource));
LoadJavascript("chrome://foxmarks/content/foxmarks-nodes.js",
typeof(Node));
LoadJavascript("chrome://foxmarks/content/foxmarks-command.js",
typeof(Command));
LoadJavascript("chrome://foxmarks/content/foxmarks-core.js",
typeof(Synchronize));
LoadJavascript("chrome://foxmarks/content/foxmarks-network.js",
typeof(Request));
LoadJavascript("chrome://foxmarks/content/foxmarks-json.js",
"undefined");
LoadJavascript("chrome://foxmarks/content/shared/Base64.js",
typeof(Base64));
LoadJavascript("chrome://foxmarks/content/shared/CreateAESManager.js",
typeof(CreateAESManager));
LoadJavascript("chrome://foxmarks/content/foxmarks-utils.js",
typeof(forEach));
LoadJavascript("chrome://foxmarks/content/foxmarks-unittest.js",
typeof(gFoxmarksUT));
LoadJavascript("chrome://foxmarks/content/foxmarks-uitools.js",
typeof(Xmarks.OpenWindowByType));
if("@mozilla.org/login-manager;1" in Cc){
LoadJavascript("chrome://foxmarks/content/foxmarks-password.js",
typeof(PasswordDatasource));
}
LoadJavascript("chrome://foxmarks/content/foxmarks-server.js",
typeof(SyncServer));
}
var logStream = null;
function removeTempLogFile(){
var fileremoved = Cc['@mozilla.org/file/directory_service;1']
.getService(Ci.nsIProperties)
.get('ProfD', Ci.nsIFile);
fileremoved.append("xmarks.temp.log");
try {
fileremoved.remove(false);
} catch(e){}
}
function logMoveFile(){
try {
var file = Cc['@mozilla.org/file/directory_service;1']
.getService(Ci.nsIProperties)
.get('ProfD', Ci.nsIFile);
file.append("xmarks.log");
var dir = Cc['@mozilla.org/file/directory_service;1']
.getService(Ci.nsIProperties)
.get('ProfD', Ci.nsIFile);
removeTempLogFile();
file.moveTo(dir, "xmarks.temp.log");
var fromstream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
var tostream = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
fromstream.init(file, -1, 0x01, 0);
var logSeek = fromstream.QueryInterface(Ci.nsISeekableStream);
var lread = fromstream.QueryInterface(Ci.nsILineInputStream);
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var i = 100 * 1024;
if(i > file.fileSize){
i = file.fileSize;
}
var filenew = Cc['@mozilla.org/file/directory_service;1']
.getService(Ci.nsIProperties)
.get('ProfD', Ci.nsIFile);
filenew.append("xmarks.log");
tostream.init(filenew, 0x02 | 0x08 | 0x10, 0664, 0);
logSeek.seek(logSeek.NS_SEEK_END, -i);
var buf;
var cont = true;
var lineData = {};
var ctr = 0;
// throw out the first one; could be mid line
cont = lread.readLine(lineData);
while(cont){
lineData = {};
cont = lread.readLine(lineData);
if(cont){
buf = converter.ConvertToUnicode(lineData.value) + "\n";
tostream.write(buf, buf.length);
}
}
} catch(e){
Components.utils.reportError(e);
} finally {
if(fromstream !== undefined)
fromstream.close();
if(tostream !== undefined)
tostream.close();
}
removeTempLogFile();
}
function logFileOpen() {
var file = Cc['@mozilla.org/file/directory_service;1']
.getService(Ci.nsIProperties)
.get('ProfD', Ci.nsIFile);
var needsTruncate = false;
var filesize = 0;
file.append("xmarks.log");
// check the file size
try {
if(file.isFile()){
filesize = file.fileSize;
}
if(filesize > 500 * 1024 && Xmarks.gSettings.truncateLog ){
logMoveFile();
}
} catch(e) {
// Components.utils.reportError(e);
}
try {
logStream = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
// use write, append, create
logStream.init(file, 0x02 | 0x08 | 0x10, 0664, 0);
} catch (e) {
// We failed to open. Close and try again next time.
logFileClose();
}
}
function logFileClose() {
try {
logStream.close();
} catch (e) {}
logStream = null;
}
var gFailureCount = 0;// number of consecutive times we've failed
var gBackoffUntil = 0;// if we've been failing, our backoff time (ms since 1970)
var gServerBackoff =
{ 'bookmarks': 0,
'passwords': 0,
min: function(){
return Math.min(this['bookmarks'], this['passwords']);
},
max: function(){
return Math.max(this['bookmarks'], this['passwords']);
},
clear: function(){
this['bookmarks'] = 0;
this['passwords'] = 0;
}
}; // seconds server wants us to back off
function ReturnErrorMsg(code, msg, restoreState, noBackoff) {
Xmarks.gSettings.lastError = code;
Xmarks.gSettings.lastError = code;
Xmarks.Notify({status: code, msg: msg });
ClearBusy();
SetState(restoreState ? restoreState : ((code == 503 || code == 2)
? "dirty" : "error"));
Xmarks.LogWrite("Returned error: " + msg + "(" + code + ")");
if(code != 2 && !noBackoff){
var d = new Date();
// Initial back-off is 15 minutes, doubling with each error
gBackoffUntil = d.getTime() + 1000 * (Math.max(
15 * 60 * Math.pow(2, gFailureCount++),
gServerBackoff.max()) + Math.floor(Math.random() * 15));
gServerBackoff.clear();;
var retry = new Date();
retry.setTime(gBackoffUntil);
Xmarks.LogWrite("Will retry at " + retry);
}
FoxmarksSyncService.lastError = code;
}
function ReturnErrorCode(code) {
ReturnErrorMsg(code, Xmarks.MapError(code));
}
function ReturnSuccess(msgname, args, restoreState) {
if (args == null) {
var args = {};
}
args.status = 0;
args.msg = Xmarks.Bundle().GetStringFromName(msgname);
SetState(restoreState ? restoreState : "ready");
ClearBusy();
gFailureCount = 0;
FoxmarksSyncService.lastError = 0;
Xmarks.LogWrite("Success: " + Xmarks.Bundle().GetStringFromName(msgname));
Xmarks.Notify(args);
}
function SetBusy() {
if (IsBusy._busy) {
return false;
} else {
IsBusy._busy = true;
SetState("working");
return true;
}
}
function ClearBusy() {
IsBusy._busy = false;
}
function IsBusy() {
return IsBusy._busy;
}
IsBusy._busy = false;
function GetState() {
return GetState._state;
}
GetState._state = "ready";
function SetState(newstate) {
if (newstate == GetState()) {
return;
}
var os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
os.notifyObservers(null, "foxmarks-statechange", newstate);
GetState._state = newstate;
}
// Internal callbacks
function LogStart(op, dest) {
Xmarks.LogWrite("------ Xmarks/" + Xmarks.FoxmarksVersion() + " (" +
FoxmarksSyncService.getStorageEngine("bookmarks") + ") starting " + op +
" with " + dest + " ------");
}
///////////////////////////////////////////////////////////////////////////
//
// nsFoxmarksService
//
var FoxmarksSyncService = null; // set during initialization to instance object
function nsFoxmarksService() {
LoadFiles();
}
nsFoxmarksService.prototype = {
/////////////////////////////////////////////////////////////////////////
// nsIFoxmarksService
timer: null,
_server: null,
lastmodified: null,
status: function(syncType) {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("status", Xmarks.gSettings.host);
if(syncType === undefined)
syncType = "bookmarks";
this.server.status(syncType, function(status, response){
if (status) {
ReturnErrorCode(status);
}
else {
ReturnSuccess("msg.accountverified", response);
}
});
return true;
},
extstatus: function(syncType) {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("extstatus", Xmarks.gSettings.host);
if(syncType === undefined)
syncType = "bookmarks";
this.server.extstatus(syncType, function(status, response){
if (status) {
ReturnErrorCode(status);
}
else {
ReturnSuccess("msg.accountverified", response);
}
});
return true;
},
purgepasswords: function(){
LogStart("purgepasswords", Xmarks.gSettings.host);
this.server.purgepasswords(function(status){
if (!status) {
ReturnSuccess("msg.synccompleted");
}
else {
ReturnErrorCode(status);
}
});
return true;
},
restore: function(rev) {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("Restoring to Revision: " + rev, Xmarks.gSettings.host);
this.server.restore(rev, function(status, response){
if (status) {
ReturnErrorCode(status);
}
else {
ReturnSuccess("msg.restore", response);
}
});
return true;
},
getrevision: function(rev) {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("Getting Revision: " + rev, Xmarks.gSettings.host);
this.server.getrevision(rev, function(status, response){
if (status) {
ReturnErrorCode(status);
}
else {
ReturnSuccess("msg.getrevision", response);
}
});
return true;
},
getrevisions: function() {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("getrevisions", Xmarks.gSettings.host);
this.server.getrevisions(function(status, response){
if (status) {
ReturnErrorCode(status);
}
else {
ReturnSuccess("msg.getrevisions", response);
}
});
return true;
},
verifypin: function(pin) {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("verify pin", Xmarks.gSettings.host);
this.server.verifypin(pin, function(status, response){
if (status) {
ReturnErrorCode(status);
}
else {
ReturnSuccess("msg.pinverified", response);
}
});
return true;
},
synchronize: function(automatic) {
var prevState = GetState();
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("sync", Xmarks.gSettings.host);
this.server.manual = automatic === true ? false : true;
this.server.sync(prevState, function(status){
if (!status) {
ReturnSuccess("msg.synccompleted");
}
else {
ReturnErrorCode(status);
}
});
return true;
},
synchronizeInitial: function (remoteIsMaster, doMerge) {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("initial sync", Xmarks.gSettings.host);
this.server.manual = true;
// We need to self correct for password sync. If there is an
// uploadReq == true, we know it doesn't have data on the server.
// if it's false, we should force a merge per our PRD.
if(Xmarks.gSettings.isSyncEnabled("passwords")){
// Set default higher if we're doing password sync
Xmarks.gSettings.securityLevel = 1;
if(!Xmarks.gSettings.mustUpload("passwords")){
Xmarks.gSettings.setMustMerge("passwords", true);
}
}
if (doMerge) {
this.server.merge(!remoteIsMaster, Finished);
} else {
if (remoteIsMaster) {
this.server.download(Finished);
} else {
this.server.upload(Finished);
}
}
return true;
function Finished(status) {
if (!status) {
ReturnSuccess("msg.synccompleted");
} else {
ReturnErrorCode(status);
}
}
},
upload: function () {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("upload", Xmarks.gSettings.host);
this.server.manual = true;
this.server.upload(function(status){
if (!status) {
ReturnSuccess("msg.uploadcompleted");
}
else {
ReturnErrorCode(status);
}
});
return true;
},
download: function () {
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("download", Xmarks.gSettings.host);
this.server.manual = true;
this.server.download(function(status){
if (!status) {
ReturnSuccess("msg.remotefilecopied");
}
else {
ReturnErrorCode(status);
}
});
return true;
},
_handleDataResponse: function(response){
var os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
os.notifyObservers(null, "foxmarks-dataservice", response.toSource());
},
getSimilarSites: function(url) {
LogStart("getSimilarSites", Xmarks.gSettings.apiHost);
this.server.getSimilarSites(url, this._handleDataResponse);
return true;
},
getTurboTags: function(url) {
LogStart("getTurboTags", Xmarks.gSettings.apiHost);
this.server.getTurboTags(url, this._handleDataResponse);
return true;
},
updateReview: function(url, url_id, rating, review) {
LogStart("updateReview", Xmarks.gSettings.apiHost);
this.server.updateReview(url, url_id, rating, review,
this._handleDataResponse);
return true;
},
getProfileNames: function() {
var prevState = GetState();
var funcFinished = function(status, response) {
if (!status) {
Xmarks.LogWrite("GetProfileNames succeeded; response is " +
response.toSource());
ReturnSuccess("error.0", response, prevState);
} else {
ReturnErrorMsg(status, Xmarks.MapError(status), prevState);
}
};
// return if we're currently processing another request
if (!SetBusy()) {
return false;
}
LogStart("getProfileNames", Xmarks.gSettings.acctMgrHost);
if (this.server.getProfileNames) {
this.server.getProfileNames(funcFinished);
return true;
} else {
return false;
}
},
launchSuccessPage: function(){
this.server.countItems("bookmarks",
"bookmark", function(status, num_bookmarks){
var currver = Xmarks.FoxmarksVersion();
// We used to set the protocol from Xmarks.gSettings.httpProtocol
// but that causes warnings when the dest page contains non-HTTPS
// content, so we peg the protocol as http.
Xmarks.OpenInNewTab("http://" + Xmarks.gSettings.webHost +
"/firefox/success/" + currver, true,
FoxmarksBuildPostData(num_bookmarks));
Xmarks.gSettings.currVersion = currver;
});
},
cancel: function() {
this.server.cancel();
},
datacancel: function() {
this.server.datacancel();
},
logWrite: function (msg) {
if (!logStream)
logFileOpen();
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth() + 1; if (month < 10) month = "0" + month;
var day = d.getDate(); if (day < 10) day = "0" + day;
var hour = d.getHours(); if (hour < 10) hour = "0" + hour;
var minute = d.getMinutes(); if (minute < 10) minute = "0" + minute;
var sec = d.getSeconds(); if (sec < 10) sec = "0" + sec;
// format is [YYYY-MM-DD HH:MM:SS] msg\n
var string = "[" + year + "-" + month + "-" + day + " " + hour + ":" +
minute + ":" + sec + "] " + msg + "\n";
if(Xmarks.gSettings.getDebugOption("dumplog"))
dump("Xmarks: " + string + "\n");
logStream.write(string, string.length)
},
getState: function() {
return GetState();
},
_password: null,
_pin: null,
_auth: null,
getAuth: function() {
return this._auth;
},
setAuth: function(auth) {
this._auth = auth;
},
getPassword: function() {
return this._password;
},
setPassword: function(password) {
this._password = password;
},
getPin: function() {
return this._pin;
},
setPin: function(password) {
this._pin = password;
},
getStorageEngine: function(synctype) {
return getDatasourceAttribute(synctype, "engine");
},
getLastError: function() {
return this.lastError;
},
lastError: 0,
_uninstall: false,
_channel: null,
_pingListener: {
onStartRequest: function () {},
onDataAvailable: function () {},
onStopRequest: function () {},
onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
this._newchannel = aNewChannel;
},
getInterface: function (aIID) {
try {
return this.QueryInterface(aIID);
} catch (e) {
throw Components.results.NS_NOINTERFACE;
}
},
onProgress : function (aRequest, aContext, aProgress, aProgressMax) { },
onStatus : function (aRequest, aContext, aStatus, aStatusArg) { },
onRedirect : function (aOldChannel, aNewChannel) { },
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
aIID.equals(Components.interfaces.nsIChannelEventSink) ||
aIID.equals(Components.interfaces.nsIProgressEventSink) ||
aIID.equals(Components.interfaces.nsIHttpEventSink) ||
aIID.equals(Components.interfaces.nsIStreamListener))
return this;
throw Components.results.NS_NOINTERFACE;
}
},
pingServer: function(topic){
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
// create an nsIURI
var attrs = [];
var session = Date.now().toString(36);
attrs.push("app=" + "jezebel");
attrs.push("mid=" + Xmarks.gSettings.machineId);
attrs.push("abgroup=" + Xmarks.gSettings.abgroup);
attrs.push("sess=" + session);
attrs.push("page=" + topic);
attrs.push("username=" + Xmarks.gSettings.username);
attrs.push("no_cache=" + Date.now().toString(36));
var query = attrs.join("&");
var url = Xmarks.gSettings.httpProtocol + "tr.xmarks.com/tracking/impressions.gif?" + query;
this._pingRequest = new Request(
"GET",
url,
null,
{
isAuthRequest: false,
headers: null,
ignoreBody: true,
ignoreAuthTokens: true
}
);
this._pingRequest.Start(function(){});
},
getLastModified: function(synctype) {
return FoxmarksSyncService.lastmodified;
},
get server() {
if (!this._server) {
this._server = new SyncServer();
}
return this._server;
},
/////////////////////////////////////////////////////////////////////////
//
// nsIObserver
observe: function(subject, topic, data) { // called at startup
var timerCallback = {
notify: function(timer) {
var now = new Date().getTime();
// scan entire bookmark set to find
// last modified date for entire set
// XXX: Implement
// Do automatic sync if necessary
if (!IsBusy() && (!gFailureCount || now > gBackoffUntil) &&
Xmarks.gSettings.synchOnTimer && Xmarks.gSettings.haveSynced) {
if (Xmarks.gSettings.minutesSinceLastSync >
Xmarks.gSettings.autoSynchFreq) {
FoxmarksSyncService.synchronize(true);
} else {
if (FoxmarksSyncService.lastmodified && Xmarks.gSettings.haveSynced &&
FoxmarksSyncService.lastmodified >
Date.parse(Xmarks.gSettings.lastSynchDate) &&
now - FoxmarksSyncService.lastmodified > 5 * 60 * 1000) {
FoxmarksSyncService.synchronize(true);
}
}
}
}
}
if (topic == "app-startup") {
// Pre-initialization here.
var os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
os.addObserver(this, "quit-application-requested", false);
os.addObserver(this, "foxmarks-datasourcechanged", false);
os.addObserver(this, "foxmarks-rununittest", false);
os.addObserver(this, "foxmarks-unittesterror", false);
os.addObserver(this, "foxmarks-tr", false);
os.addObserver(this, "earlyformsubmit", false);
os.addObserver(this, "final-ui-startup", false);
os.addObserver(this, "em-action-requested", false);
os.addObserver(this, "quit-application-granted", false);
os.addObserver(this, "foxmarks-showsettingpane", false);
os.addObserver(this, "foxmarks-realstart", false);
} else if (topic == "final-ui-startup") {
// check to see if crypto hash is installed (bug #7397)
// if we error, wait a while and try again
var counter = 0;
var cryptoCallback = {
notify: function() {
// give it another shot
try {
var hash = Cc["@mozilla.org/security/hash;1"].
createInstance(Ci.nsICryptoHash);
// otherwise, wait again if we have time
} catch(e){
counter++;
Xmarks.LogWrite("Error: Cryptohash not initialized");
if(counter < 10){
var timer = Cc["@mozilla.org/timer;1"].
createInstance(Ci.nsITimer);
timer.initWithCallback(cryptoCallback, 500,
Ci.nsITimer.TYPE_ONE_SHOT);
}
return;
}
FoxmarksCheckForServerChanges();
}
};
var timer = Cc["@mozilla.org/timer;1"].
createInstance(Ci.nsITimer);
timer.initWithCallback(cryptoCallback, 0,
Ci.nsITimer.TYPE_ONE_SHOT);
} else if (topic == "foxmarks-realstart") {
// Real initialization starts here.
FoxmarksSyncService = this;
Xmarks.UpdateToXMarks();
var dsList = loadDatasourceSet(true);
FoxmarksSyncService.nat = {};
for(var x = 0; x < dsList.length; x++)
FoxmarksSyncService.nat[dsList[x].syncType] = dsList[x].WatchForChanges(this.server);
if (!Xmarks.gSettings.wizardSuppress && !Xmarks.gSettings.useOwnServer &&
!Xmarks.gSettings.haveSynced) {
Xmarks.LogWrite("Starting Wizard: Never Synched");
FoxmarksLaunchSetupWizard();
} else if (Xmarks.gSettings.majorVersion < 2) {
Xmarks.LogWrite("Starting Wizard: Major Upgrade");
Xmarks.gSettings.majorVersion = 3;
FoxmarksLaunchSetupWizard();
} else {
// need to check for upgrades here
Xmarks.gSettings.majorVersion = 3;
var currver = Xmarks.FoxmarksVersion();
var lastver = Xmarks.gSettings.currVersion;
var ca = currver.split(".");
var la = lastver.split(".");
var newver =false;
if(ca.length != la.length){
newver = true;
} else {
for(var x=0; x < ca.length-1; x++){
if(parseInt(ca[x]) != parseInt(la[x])){
newver = true;
break;
}
}
}
if(newver){
FoxmarksLaunchUpgradePage();
}
}
this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this.timer.initWithCallback(timerCallback, 1000*60,
Ci.nsITimer.TYPE_REPEATING_SLACK);
} else if (topic == "foxmarks-tr") {
this.pingServer(data);
} else if (topic == "quit-application-requested") {
HandleShutdown();
} else if(topic == "em-action-requested"){
subject.QueryInterface(Components.interfaces.nsIUpdateItem);
if(subject.id == "foxmarks@kei.com"){
switch(data){
case 'item-uninstalled':
this._uninstall = true;
this.pingServer("uninstall");
break;
case 'item-disabled':
this.pingServer("disable");
break;
case 'item-cancel-action':
if(this._uninstall == false){
this.pingServer("cancel-disable");
} else {
this.pingServer("cancel-uninstall");
}
this._uninstall = false;
break;
}
}
} else if(topic == "quit-application-granted"){
if(this._uninstall){
Xmarks.gSettings.clearAllPrefs();
}
} else if(topic == "foxmarks-showsettingpane"){
if(data.length > 0){
Xmarks.OpenFoxmarksSettingsDialog(data);
}
} else if (topic == "foxmarks-unittesterror"){
try {
ReturnErrorCode(parseInt(data));
}
catch(e){
Components.utils.reportError(e);
}
} else if (topic == "foxmarks-rununittest"){
this.server.runUnitTest();
} else if (topic == "foxmarks-datasourcechanged") {
var a = data.split(';');
this.lastmodified = parseInt(a[0]);
var okState = (GetState() == "ready" || GetState() == "unknown");
if (okState && Xmarks.gSettings.haveSynced &&
Xmarks.gSettings.isSyncEnabled(a[1]) &&
this.lastmodified > Date.parse(Xmarks.gSettings.lastSynchDate)) {
SetState("dirty");
}
} else {
Xmarks.LogWrite("Yikes unknown topic " + topic);
}
},
/////////////////////////////////////////////////////////////////////////
// nsIFormSubmitObserver
notify : function (formElement, aWindow, actionURI) {
if(FoxmarksSyncService && FoxmarksSyncService.nat["passwords"]
&& Xmarks && Xmarks.gSettings.isSyncEnabled("passwords")
){
Xmarks.LogWrite("Before Early Form Submit");
FoxmarksSyncService.nat["passwords"].formsubmit(formElement);
Xmarks.LogWrite("After Early Form Submit");
}
return true;
},
/////////////////////////////////////////////////////////////////////////
// nsIClassInfo
getInterfaces: function (aCount) {
var interfaces = [Ci.nsIFoxmarksService,
Ci.nsIObserver,
Ci.nsIFormSubmitObserver,
Ci.nsiRDFObserver];
aCount.value = interfaces.length;
return interfaces;
},
getHelperForLanguage: function (aLanguage) {
return null;
},
get contractID() {
return "@foxcloud.com/extensions/foxmarks;1";
},
get classDescription() {
return "Foxmarks Service";
},
get classID() {
return Components.ID("{49ace257-6111-48b2-a988-f9eb38b0fa58}");
},
get implementationLanguage() {
return Ci.nsIProgrammingLanguage.JAVASCRIPT;
},
get flags() {
return Ci.nsIClassInfo.SINGLETON;
},
/////////////////////////////////////////////////////////////////////////
// nsISupports
QueryInterface: function (aIID) {
if (!aIID.equals(Ci.nsIFoxmarksService) &&
!aIID.equals(Ci.nsISupports) &&
!aIID.equals(Ci.nsIRDFObserver) &&
!aIID.equals(Ci.nsIFormSubmitObserver) &&
!aIID.equals(Ci.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
var gModule = {
_firstTime: true,
registerSelf: function (aComponentManager, aFileSpec, aLocation, aType) {
if (this._firstTime) {
this._firstTime = false;
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
}
aComponentManager = aComponentManager.
QueryInterface(Ci.nsIComponentRegistrar);
for (var key in this._objects) {
var obj = this._objects[key];
aComponentManager.registerFactoryLocation(obj.CID, obj.className,
obj.contractID, aFileSpec, aLocation, aType);
}
// Make the Foxmarks Service a startup observer
var cm = Cc["@mozilla.org/categorymanager;1"].
getService(Ci.nsICategoryManager);
cm.addCategoryEntry("app-startup", this._objects.service.className,
"service," + this._objects.service.contractID, true, true, null);
},
getClassObject: function (aComponentManager, aCID, aIID) {
if (!aIID.equals(Ci.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
for (var key in this._objects) {
if (aCID.equals(this._objects[key].CID))
return this._objects[key].factory;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
},
_makeFactory: #1= function(ctor) {
return {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return (new ctor()).QueryInterface(iid);
}
};
},
_objects: {
service: { CID : nsFoxmarksService.prototype.classID,
contractID : nsFoxmarksService.prototype.contractID,
className : nsFoxmarksService.prototype.classDescription,
factory : #1#(nsFoxmarksService)
}
},
canUnload: function (aComponentManager)
{
return true;
}
};
function NSGetModule(compMgr, fileSpec)
{
return gModule;
}